package service;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.List;

import server.Request;
import server.Response;
import util.Consts;
import dao.Config;
import entity.ExamInfo;
import entity.QuestionInfo;
import entity.User;
import exception.ExamNotFinishException;
import exception.NameOrPasswordException;

//TODO Day5
public class ExamServiceAgentImpl implements ExamService {

	private Config config;
	private String sessionId = null;

	public ExamServiceAgentImpl(Config config) {
		this.config = config;
	}

	public User login(int id, String pwd) throws NameOrPasswordException {
		Response res = sendRequest("login", new Class[] { int.class,
				String.class }, new Object[] { id, pwd });
		if (res.isSuccess())
			return (User) res.getValue();
		if (res.getState() == Consts.ERR_NAME_OR_PWD) {
			throw new NameOrPasswordException(res.getMessage());
		}
		throw new RuntimeException(res.getMessage());
	}

	public ExamInfo start() {
		Response res = sendRequest("start", new Class[] {}, new Object[] {});
		if (res.isSuccess())
			return (ExamInfo) res.getValue();
		throw new RuntimeException(res.getMessage());
	}

	public QuestionInfo getQuestion(int index) {
		Response res = sendRequest("getQuestion", new Class[] { int.class },
				new Object[] { index });
		if (res.isSuccess())
			return (QuestionInfo) res.getValue();
		throw new RuntimeException(res.getMessage());

	}

	public void sendAnswers(int questionIndex, List<Integer> answers) {
		Response res = sendRequest("sendAnswers", new Class[] { int.class,
				List.class }, new Object[] { questionIndex, answers });
		if (res.isSuccess())
			return;
		throw new RuntimeException(res.getMessage());
	}

	public int commit() {
		Response res = sendRequest("commit", new Class[] {}, new Object[] {});
		if (res.isSuccess())
			return (Integer) res.getValue();
		throw new RuntimeException(res.getMessage());
	}

	public int result() throws ExamNotFinishException {
		Response res = sendRequest("result", new Class[] {}, new Object[] {});
		if (res.isSuccess())
			return (Integer) res.getValue();
		if (res.getState() == Consts.ERR_EXAM_NOT_FINISH) {
			throw new ExamNotFinishException(res.getMessage());
		}
		throw new RuntimeException(res.getMessage());

	}

	/**
	 * 想指定的服务器发送请求, 出来返回结果
	 */
	private Response sendRequest(String method, Class[] argTypes, Object[] args) {
		String host = config.getString("ServerIP");
		int port = config.getInt("ServerPort");
		try {
			Socket socket = new Socket(host, port);
			ObjectOutputStream out = new ObjectOutputStream(socket
					.getOutputStream());
			ObjectInputStream in = new ObjectInputStream(socket
					.getInputStream());
			// 创建对服务器的请求
			Request request = new Request(sessionId, method, argTypes, args);
			// 发送请求到服务器
			out.writeObject(request);
			out.flush();
			// 接受服务器的反馈
			Response r = (Response) in.readObject();
			// 将服务器的返回SessionID 保存起来
			System.out.println("Response:" + r);
			sessionId = r.getSessionId();
			socket.close();// 通信结束关闭掉连接
			return r;
		} catch (UnknownHostException e) {
			e.printStackTrace();
			throw new RuntimeException("网络连接故障!", e);
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException("网络连接故障!", e);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			throw new RuntimeException("网络故障!", e);
		}
	}

	public static void main(String[] args) throws Exception {
		Config config = new Config("client.properties");
		ExamServiceAgentImpl service = new ExamServiceAgentImpl(config);
		User u = service.login(1001, "1234");
		System.out.println(u);
	}

	@Override
	public String getRule() {
		Response response=sendRequest("getRule",new Class[]{},new Object[]{});
		if(response.isSuccess()){
			return (String)response.getValue();
		}
		throw new RuntimeException(response.getMessage());
	}

/*	@Override
	public void sendAnswers(int questionIndex, List<Integer> answer) {
		Response response = sendRequest("sendAnswers", new Class[] { int.class,
				List.class }, new Object[] { questionIndex, answer });
		throw new RuntimeException(response.getMessage());
	}*/
}
